package com.sy.simpleegg.platform.whm.service

import android.app.Service
import android.content.Context
import android.content.Intent
import android.net.ConnectivityManager
import android.os.Handler
import android.os.IBinder
import android.util.Log
import android.widget.Toast
import com.sy.simpleegg.platform.whm.MQConfig
import com.sy.simpleegg.platform.whm.bean.MqttData
import com.sy.simpleegg.util.BoardApiUtil
import com.sy.simpleegg.util.ByteUtil
import com.sy.logger.Logger
import org.eclipse.paho.android.service.MqttAndroidClient
import org.eclipse.paho.client.mqttv3.IMqttActionListener
import org.eclipse.paho.client.mqttv3.IMqttDeliveryToken
import org.eclipse.paho.client.mqttv3.IMqttToken
import org.eclipse.paho.client.mqttv3.MqttCallback
import org.eclipse.paho.client.mqttv3.MqttConnectOptions
import org.eclipse.paho.client.mqttv3.MqttException
import org.eclipse.paho.client.mqttv3.MqttMessage
import java.util.Arrays

class TqMqttService : Service() {
    //    public String CLIENTID = String.valueOf(new Date().getTime());//客户端标识（唯一性）
    var CLIENTID = BoardApiUtil.getDeviceId()
    private var mMqttConnectOptions: MqttConnectOptions? = null
    private var subscribeCount = 0

    //MQTT是否连接成功的监听
    private val iMqttActionListener: IMqttActionListener = object : IMqttActionListener {
        override fun onSuccess(arg0: IMqttToken) {
            Log.i(TAG, "Mqtt服务器连接成功")
            if (sMqttData != null) {
                sMqttData!!.connect(true)
            }
            try {
                //可先将订阅接口全部订阅，后期只需要进行主题消息发送
//                for (int i = 0; i < response.length; i++) {
//                    mqttAndroidClient.subscribe(response[i], Qos);
//                }
                val response = arrayOf(
                    "hardware/server/" + devType + "/" + devNumber + "/" + MQConfig.PROTOCOL_VER1 + "/#",
                    "hardware/server/" + devType + "/" + devNumber + "/" + MQConfig.PROTOCOL_VER2 + "/#"
                )
                if (subscribeCount != 0) {
                    subscribeCount = 0
                }
                for (i in response.indices) {
                    mqttAndroidClient!!.subscribe(
                        response[i],
                        Qos,
                        null,
                        object : IMqttActionListener {
                            override fun onSuccess(iMqttToken: IMqttToken) {
                                Log.i(TAG, "主题订阅成功:" + Arrays.toString(iMqttToken.topics))
                                subscribeCount++
                                if (subscribeCount == response.size && sMqttData != null) {
                                    subscribeCount = 0
                                    sMqttData!!.onTopicSuccess()
                                }
                            }

                            override fun onFailure(iMqttToken: IMqttToken, throwable: Throwable) {
                                Log.i(TAG, "主题订阅失败:" + Arrays.toString(iMqttToken.topics))
                            }
                        })
                }
            } catch (e: MqttException) {
                e.printStackTrace()
            }
        }

        override fun onFailure(arg0: IMqttToken, arg1: Throwable) {
            arg1.printStackTrace()
            Log.i(TAG, "Mqtt连接失败！")
            doClientConnection() //连接失败，重连（可关闭服务器进行模拟）
        }
    }

    //订阅主题的回调
    private val mqttCallback: MqttCallback = object : MqttCallback {
        @Throws(Exception::class)
        override fun messageArrived(topic: String, message: MqttMessage) {
            val result: String = ByteUtil.bytes2HexStr(message.payload)
            Log.i(TAG, "Mqtt收到消息： " + Arrays.toString(message.payload))
            Log.i(TAG, "Mqtt收到消息： $result")
            Log.i(TAG, "Mqtt收到消息主题： $topic")
            //收到消息后进行响应
            if (sMqttData != null) {
                sMqttData!!.onResult(topic, result)
            } else {
                Log.i(TAG, "sMqttData == null，请设置消息监听器")
            }
        }

        override fun deliveryComplete(arg0: IMqttDeliveryToken) {
            try {
                Log.i(
                    TAG,
                    if (arg0.isComplete) "消息发送成功:" + arg0.message.toString() else "消息发送失败"
                )
            } catch (e: MqttException) {
                e.printStackTrace()
            }
        }

        override fun connectionLost(arg0: Throwable) {
            Log.i(TAG, "连接断开 ")
            if (sMqttData != null) {
                sMqttData!!.connect(false)
            }
            Toast.makeText(applicationContext, "Mqtt连接断开，正在重连！", Toast.LENGTH_LONG).show()
            doClientConnection() //连接断开，重连
        }
    }

    override fun onCreate() {
        super.onCreate()
        init()
    }

    /**
     * 初始化
     */
    private fun init() {
        val serverURI = MQConfig.HOST //服务器地址（协议+地址+端口号）
        mqttAndroidClient = MqttAndroidClient(this, serverURI, CLIENTID)
        mqttAndroidClient!!.setCallback(mqttCallback) //设置监听订阅消息的回调
        mMqttConnectOptions = MqttConnectOptions()
        mMqttConnectOptions!!.isCleanSession = true //设置是否清除缓存
        mMqttConnectOptions!!.connectionTimeout = 30 //设置超时时间，单位：秒
        mMqttConnectOptions!!.keepAliveInterval = 10 //设置心跳包发送间隔，单位：秒
        mMqttConnectOptions!!.isAutomaticReconnect = true // 设置自动重连
        mMqttConnectOptions!!.userName = MQConfig.nameUser //设置用户名
        mMqttConnectOptions!!.password = MQConfig.passWord.toCharArray() //设置密码
        if (mqttAndroidClient != null) {
            doClientConnection()
        }
    }

    /**
     * 连接MQTT服务器
     */
    private fun doClientConnection() {
        if (!mqttAndroidClient!!.isConnected && isConnectIsAvaliable) {
            try {
                mqttAndroidClient!!.connect(mMqttConnectOptions, null, iMqttActionListener)
            } catch (e: MqttException) {
                e.printStackTrace()
            }
        }
    }

    private val isConnectIsAvaliable: Boolean
        /**
         * 判断网络是否连接
         */
        private get() {
            val connectivityManager =
                this.applicationContext.getSystemService(CONNECTIVITY_SERVICE) as ConnectivityManager
            val info = connectivityManager.activeNetworkInfo
            return if (info != null && info.isAvailable) {
                val name = info.typeName
                Log.i(TAG, "当前网络名称：$name")
                true
            } else {
                Log.i(TAG, "没有可用网络")
                /*没有可用网络的时候，延迟3秒再尝试重连*/Handler().postDelayed(
                    { doClientConnection() }, 3000
                )
                false
            }
        }

    override fun onDestroy() {
        try {
            mqttAndroidClient!!.disconnect() //断开连接
            mqttAndroidClient!!.unregisterResources()
        } catch (e: MqttException) {
            e.printStackTrace()
        }
        super.onDestroy()
    }

    override fun onBind(intent: Intent): IBinder? {
        return null
    }

    companion object {
        val TAG = TqMqttService::class.java.simpleName
        private const val Qos = 1
        private var mqttAndroidClient: MqttAndroidClient? = null

        /**
         * 设备类型，设备编号，协议通讯版本号
         */
        private var devType: String? = null
        private var devNumber: String? = null
        private var ver: String? = null
        fun setParams(devType: String?, devNumber: String?, ver: String?) {
            Companion.devType = devType
            Companion.devNumber = devNumber
            Companion.ver = ver
        }

        /**
         * 开启服务
         */
        fun startService(mContext: Context) {
            mContext.startService(Intent(mContext, TqMqttService::class.java))
        }

        /**
         * 发布 （向服务器发送消息）
         *
         * @param topic   主题
         * @param message 消息
         */
        fun publish(topic: String?, message: String) {
            val qos = Qos
            val retained = false
            try {
                //参数分别为：主题、消息的字节数组、服务质量、是否在服务器保留断开连接后的最后一条消息
                if (mqttAndroidClient != null) {
                    mqttAndroidClient!!.publish(topic, message.toByteArray(), qos, retained)
                }
            } catch (e: MqttException) {
                e.printStackTrace()
            }
        }

        fun publish(protocolVer: String, message: ByteArray?) {
            try {
                val qos = Qos
                val retained = false
                try {
                    //参数分别为：主题、消息的字节数组、服务质量、是否在服务器保留断开连接后的最后一条消息
                    if (mqttAndroidClient != null) {
                        var topic = ""
                        topic = "hardware/client/" + devType + "/" + devNumber + "/" + protocolVer
                        Logger.d("发布消息主题：$topic")
                        mqttAndroidClient!!.publish(topic, message, qos, retained)
                    }
                } catch (e: MqttException) {
                    e.printStackTrace()
                }
            } catch (e: Exception) {
                e.printStackTrace()
                Logger.e("publish2()异常：" + e.message)
            }
        }

        /**
         * 注册订阅
         * 订阅就是被动接受（接收另一个设备发送的topic）
         */
        fun subscribes(response: String) {
            try {
                val qos = 1
                //订阅查询的主题、服务质量
                Log.i(TAG, "订阅：$response")
                if (mqttAndroidClient != null) {
                    mqttAndroidClient!!.subscribe(response, qos)
                }
            } catch (e: MqttException) {
                e.printStackTrace()
            }
        }

        val isConnected: Boolean
            get() = if (mqttAndroidClient != null) {
                mqttAndroidClient!!.isConnected
            } else false
        var sMqttData: MqttData? = null
        fun setMqttData(mqttData: MqttData?) {
            sMqttData = mqttData
        }
    }
}